/* 
 * File:   ValueRepository.h
 * Author: RedEyedKiller
 *
 * Created on 16 Οκτώβριος 2011, 4:53 μμ
 */

#ifndef VALUEREPOSITORY_H
#define	VALUEREPOSITORY_H

#include "sdl/GLColor.h"
#include "Vector2.h"
#include "Rect.h"

#include <map>
#include <list>
#include <string>
#include <boost/variant.hpp>
#include <algorithm>

/**
 * Stores all values loaded from valu files loaded via xml inclusion.
 */
class ValueRepository
{
public:

    ValueRepository()
    {
    }

    virtual ~ValueRepository()
    {
    }

    void Clear()
    {
        values.clear();
    }

    /**
     * Checks if specified file is already loaded and if not it marks it as loaded.
     * @param file
     * @return true if file is loaded, false otherwise.
     */
    bool FileLoaded(const std::string& file)
    {
        std::list<std::string>::iterator it = std::find(loadedFiles.begin(), loadedFiles.end(), file);
        if (it == loadedFiles.end())
        {
            loadedFiles.push_back(file);
            return false;
        }
        else
        {
            return true;
        }
    }

    /**
     * Registers the variable file.name of type T with the specified value. 
     * @param file
     * @param name
     * @param value
     * @return 
     */
    template <typename T>
    bool RegisterValue(const std::string& file, const std::string& name, const T& value)
    {
        std::string key = file + "." + name;
        ValueMap::iterator it = values.find(key);
        bool overwrite = (it == values.end());
#ifdef REPO_NO_OVERWRITE
        if (!overwrite)
#endif
            values[key] = value;
        return overwrite;
    }

    /**
     * Returns true or false if the requested value exists. It it exists it can be retrieved 
     * via the value reference.
     * @param key
     * @param value
     * @return 
     */
    template <typename T>
    bool GetValue(const std::string& key, T& value)
    {
        ValueMap::iterator it = values.find(key);
        if (it == values.end())
        {
            return false;
        }
        value = boost::get<T > (it->second);
        return true;
    }

private:
    typedef boost::variant<int, float, bool, std::string, gl::Color, Math::Vector2F, Math::Rect> Value;
    typedef std::map<std::string, Value> ValueMap;

    /**
     * A map with all the loaded values.
     */
    ValueMap values;

    /**
     * A list containing all loaded files.
     */
    std::list<std::string> loadedFiles;
};

#endif	/* VALUEREPOSITORY_H */

